/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controller;

import Model.Celdam;
import Model.twoWays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

/**
 *
 * @author r4wd3r
 */
public class Calculadora {

    public Calculadora() {
    }
    LambdaGeneralizado distribucion = new LambdaGeneralizado();

    private int mij(int i, int j) {
        int resultado = 0;
        resultado = twoWays.getMatriz()[i][j].getDatos();
        return resultado;
    }

    private int mpuntoj(int j) {
        int resultado = 0;
        for (int i = 0; i < twoWays.getI(); i++) {
            resultado = resultado + mij(i, j);
        }
        return resultado;
    }

    private int mipunto(int i) {
        int resultado = 0;
        for (int j = 0; j < twoWays.getI(); j++) {
            resultado = resultado + mij(i, j);
        }
        return resultado;
    }

    private double esperadoRijpunto(int i, int j) {
        double resultado = 0;
        resultado = ((double)(mpuntoj(j)) * ((double)(mipunto(i) + 1))) / 2;
        return resultado;
    }

    private double varianzaRijpunto(int i, int j) {
        double resultado = 0;
        resultado = ((double)(mpuntoj(j)) * ((double)(mipunto(i)) - (double)(mij(i, j))) * (double)(mipunto(i) + 1)) / 12;
        return resultado;
    }

    public double Kgeneralizada() {
        double resultado = 0;
        for (int j = 0; j < twoWays.getJ(); j++) {
            for (int i = 0; i < twoWays.getI(); i++) {
                resultado += (1 - ((double)(mij(i, j)) / (double)(mpuntoj(j)))) * Math.pow((((double)(rijpunto(i, j, twoWays.getMatriz())) - ((double)esperadoRijpunto(i, j))) / (Math.sqrt((double)varianzaRijpunto(i, j)))),2);
            }
        }
        return resultado;
    }

    private ArrayList<Double> ordenarDatosBloque(ArrayList<Double> arreglo) {
        ArrayList<Double> datosOrdenados = new ArrayList<Double>();
        datosOrdenados = arreglo;
        Collections.sort(datosOrdenados);
        return datosOrdenados;
    }

    private int rijk(int i, int j, double xijk) {
        int posicion = 0;
        ArrayList<Double> datosBloque = new ArrayList<Double>();
        ordenarDatosBloque(datosBloque);
        for (Double d : datosBloque) {
            if (xijk == d) {
                break;
            }
            posicion++;
        }
        return posicion;
    }

    public double generarDatos(double granMedia, double beta, int fila, int columna, double lambda1, double lambda2, double lambda3, double lambda4) {
        double dato;
        double u = Math.random();
        double tao, betax;
        betax = twoWays.getListaBetas().get(fila);
        tao = twoWays.getListaTaos().get(columna);
        System.out.println("Generar Dato: Fila " + fila + " Columna:" + columna + " Beta: " + betax + " Tao: " + tao);
        dato = granMedia + (betax) + tao + (lambda1 + ((Math.pow(u, lambda3) - (Math.pow((1 - u), lambda4))) / lambda2));
        return dato;
    }

    private double mediaGeneral(ArrayList<Double> matriz[][][]) {
        double resultado = 0;
        double cantidad = 0;
        return resultado;
    }

    private int rijpunto(int i, int j, Celdam matriz[][]) {
        int resultadoCelda = 0;
        for (int k = 0; k < matriz[i][j].getOrdenamiento().size(); k++) {
            resultadoCelda = resultadoCelda + matriz[i][j].getOrdenamiento().get(k);
        }
        return resultadoCelda;
    }

    private double rpuntojpunto(int j) {
        double resultado = 0;
        Celdam matriz[][];
        matriz = twoWays.getMatriz();
        int fin = twoWays.getI();
        for (int i = 0; i < fin; i++) {
            resultado = resultado + rijpunto(i, j, matriz);
        }
        return resultado;
    }

    private double ripuntopunto(int i) {
        int resultado = 0;
        Celdam matriz[][];
        matriz = twoWays.getMatriz();
        int fin = twoWays.getJ();
        for (int j = 0; j < fin; j++) {
            resultado = resultado + rijpunto(i, j, matriz);
        }
        return resultado;
    }

    private int Rijpunto(int i, int j, Celdam matriz[][]) {
        int resultadoCelda = 0;
        for (int k = 0; k < matriz[i][j].getSecuencias().size(); k++) {
            resultadoCelda = resultadoCelda + matriz[i][j].getSecuencias().get(k);
        }
        return resultadoCelda;
    }

    private double Rpuntojpunto(int j) {
        double resultado = 0;
        Celdam matriz[][];
        matriz = twoWays.getMatriz();
        int fin = twoWays.getI();
        for (int i = 0; i < fin; i++) {
            resultado = resultado + Rijpunto(i, j, matriz);
        }
        return resultado;
    }

    private double Ripuntopunto(int i) {
        int resultado = 0;
        Celdam matriz[][];
        matriz = twoWays.getMatriz();
        int fin = twoWays.getJ();
        for (int j = 0; j < fin; j++) {
            resultado = resultado + Rijpunto(i, j, matriz);
        }
        return resultado;
    }    
    public double j1() {
        double resultado1 = 0;
        double resultado2 = 0;
        double resultado = 0;
        
        for (int i = 0; i < twoWays.getI(); i++) {
            resultado1 = resultado1 + Ripuntopunto(i);
        }
        for (int j = 0; j < twoWays.getJ(); j++) {
            resultado2 = resultado2 +  Rpuntojpunto(j);
        }
        resultado = resultado1/resultado2;
        return resultado1;
    }
    /* k es el numero de tratamientos
     * n es el numero de bloques
     * m es el numero de datos por celda
     */

    public double estadisticaFriedman(int m, int n, int k) {
        double K = 0;
        double sumarpuntojpunto = 0;
        double m1,n1,k1;
        m1 = m;
        n1 = n;
        k1 = k;
        for (int j = 0; j < k; j++) {
            sumarpuntojpunto = sumarpuntojpunto + Math.pow(rpuntojpunto(j),2);
        }
        System.out.println("El rpuntojotapunto es!!!!!!!" + sumarpuntojpunto);
        K = ((12/(n1*k1*(Math.pow(m1,2))*((m1*k1)+1))) * (sumarpuntojpunto)) - (3 * n1 * ((m1 * k1) + 1));
        return K;
    }

    static double gammln(double xx) {
        double cof[] = new double[6];
        cof[0] = 76.18009172947146;
        cof[1] = -86.50532032941677;
        cof[2] = 24.01409824083091;
        cof[3] = -1.231739572450155;
        cof[4] = 0.1208650973866179e-2;
        cof[5] = -0.5395239384953e-5;
        double x, y, tmp, ser;
        y = x = xx;
        tmp = x + 5.5;
        tmp -= (x + 0.5) * Math.log(tmp);
        ser = 1.000000000190015;
        for (int j = 0; j <= 5; j++) {
            ser += cof[j] / ++y;
        }

        return -tmp + Math.log(2.5066282746310005 * ser / x);
    }

    public static double beta(double z, double w) {
        return Math.exp(gammln(z) + gammln(w) - gammln(z + w));
    }

    public static double beta(double z) {
        return Math.exp(gammln(z));
    }

    public double calcularValorCritico(double alfa, double lambda1, double lambda2, double lambda3, double lambda4) {
        distribucion.L1 = lambda1;
        distribucion.L2 = lambda2;
        distribucion.L3 = lambda3;
        distribucion.L4 = lambda4;
        return distribucion.calcularValorCritico(alfa);
    }
}
